<template>
  <t-drawer
    v-model:visible="drawer"
    :header="index"
    drawer-class-name="index-manage-drawer"
    size="600px"
  >
    <div class="index-manage">
      <a-tabs v-model:active-key="active" class="tab">
        <a-tab-pane key="1" title="总览" />
        <a-tab-pane key="2" title="设置" />
        <a-tab-pane key="3" title="映射" />
        <a-tab-pane key="4" title="统计信息" />
      </a-tabs>
      <a-spin :loading="loading" tip="加载中">
        <div class="content">
          <monaco-editor v-show="jsonViewShow" language="json" :model-value="data" read-only />
          <index-manage-summary
            v-show="!jsonViewShow"
            ref="indexManageSummary"
            :index="index"
            :state="state"
          />
        </div>
      </a-spin>
    </div>
    <template #footer>
      <a-dropdown trigger="click" @select="indexManage">
        <a-button type="primary">
          管理
          <icon-up />
        </a-button>
        <template #content>
          <a-doption v-if="state === 'close'" value="open">打开索引</a-doption>
          <a-doption v-else-if="state === 'open'" value="close">关闭索引</a-doption>
          <a-doption disabled value="merge">强制合并索引</a-doption>
          <a-doption value="refresh">刷新索引</a-doption>
          <a-doption value="clear">清除索引缓存</a-doption>
          <a-doption value="flush">flush索引</a-doption>
          <a-doption disabled value="freeze">冻结索引</a-doption>
          <a-doption value="remove">删除索引</a-doption>
          <a-doption disabled value="lifecycle">增加生命周期</a-doption>
        </template>
      </a-dropdown>
    </template>
  </t-drawer>
</template>
<script lang="ts">
import { contains } from "@/utils/ArrayUtil";
import IndexApi from "@/components/es/api/IndexApi";
import Assert from "@/utils/Assert";
import IndexManageSummary from "@/module/index-manage/summary.vue";
import MessageUtil from "@/utils/model/MessageUtil";
import { useIndexStore, useUrlStore } from "@/store";
import Optional from "@/utils/Optional";
import { mapState } from "pinia";
import { useIndexManageEvent } from "@/global/BeanFactory";
import MessageBoxUtil from "@/utils/model/MessageBoxUtil";
import MonacoEditor from "@/components/monaco-editor/index.vue";
import { clientInstanceGetStateApi } from "@/api";
import { formatJsonString } from "$/util";

export default defineComponent({
  name: "IndexManage",
  components: { MonacoEditor, IndexManageSummary },
  emits: ["update:modelValue"],
  data: () => ({
    drawer: false,
    active: "1",
    data: "",
    loading: false,
    index: ""
  }),
  computed: {
    ...mapState(useUrlStore, ["id"]),
    jsonViewShow() {
      return contains(["2", "3", "4"], this.active);
    },
    ...mapState(useIndexStore, ["indicesMap"]),
    state(): "open" | "close" | "" {
      let indexView = useIndexStore().indicesMap.get(this.index);
      return Optional.ofNullable(indexView)
        .map((e) => e.state)
        .orElse("");
    }
  },
  watch: {
    active(newValue: string) {
      this.assignJson(newValue);
    },
    index() {
      this.$nextTick(() => {
        this.assignJson(this.active);
      });
    }
  },
  created() {
    useIndexManageEvent.on((index) => {
      this.drawer = true;
      this.index = index;
    });
  },
  methods: {
    assignJson(newValue: string) {
      switch (newValue) {
        case "2":
          this.setting();
          break;
        case "3":
          this.mapping();
          break;
        case "4":
          this.stats();
          break;
      }
    },
    setting() {
      Assert.notNull(this.index, "索引名称不存在");
      if (!this.id) return MessageUtil.error("链接不存在");
      this.loading = true;
      clientInstanceGetStateApi(this.id, `/${this.index}/_settings`)
        .then((result) => {
          this.data = formatJsonString(result);
        })
        .catch((e) => {
          MessageUtil.error("索引设置查询错误", e);
          this.data = "{}";
        })
        .finally(() => {
          this.loading = false;
        });
    },
    mapping() {
      Assert.notNull(this.index, "索引名称不存在");
      if (!this.id) return MessageUtil.error("链接不存在");
      this.loading = true;
      clientInstanceGetStateApi(this.id, `/${this.index}/_mappings`)
        .then((result) => {
          this.data = formatJsonString(result);
        })
        .catch((e) => {
          MessageUtil.error("索引映射查询错误", e);
          this.data = "{}";
        })
        .finally(() => {
          this.loading = false;
        });
    },
    stats() {
      Assert.notNull(this.index, "索引名称不存在");
      if (!this.id) return MessageUtil.error("链接不存在");
      this.loading = true;
      clientInstanceGetStateApi(this.id, `/${this.index}/_stats`)
        .then((result) => {
          this.data = formatJsonString(result);
        })
        .catch((e) => {
          MessageUtil.error("索引状态查询错误", e);
          this.data = "{}";
        })
        .finally(() => {
          this.loading = false;
        });
    },
    indexManage(command: any) {
      this.execCommand(command)
        .then(() => {
          // 1. 发送索引更新事件
          useIndexStore().reset();
          // 3. 更新本组件
          this.assignJson(this.active);
        })
        .catch((e) => console.error(e));
    },
    execCommand(command: string): Promise<void> {
      return new Promise<void>((resolve, reject) => {
        switch (command) {
          case "open":
            IndexApi(this.index)
              ._open()
              .then((res) => MessageUtil.success(res, resolve))
              .catch((e) => MessageUtil.error("打开索引错误", e, () => reject(e)));
            break;
          case "close":
            IndexApi(this.index)
              ._close()
              .then((res) => MessageUtil.success(res, resolve))
              .catch((e) => MessageUtil.error("关闭索引错误", e, () => reject(e)));
            break;
          case "merge":
            break;
          case "refresh":
            IndexApi(this.index)
              ._refresh()
              .then((res) => MessageUtil.success(res, resolve))
              .catch((e) => MessageUtil.error("刷新索引失败", e, () => reject(e)));
            break;
          case "clear":
            IndexApi(this.index)
              ._cacheClear()
              .then((res) => MessageUtil.success(res, resolve))
              .catch((e) => MessageUtil.error("清理缓存失败", e, () => reject(e)));
            break;
          case "flush":
            IndexApi(this.index)
              ._flush()
              .then((res) => MessageUtil.success(res, resolve))
              .catch((e) => MessageUtil.error("flush刷新失败", e, () => reject(e)));
            break;
          case "freeze":
            break;
          case "remove":
            MessageBoxUtil.confirm("此操作将永久删除该索引, 是否继续?", "提示", {
              confirmButtonText: "确定",
              cancelButtonText: "取消"
            }).then(() =>
              IndexApi(this.index)
                .delete()
                .then((res) => MessageUtil.success(res, resolve))
                .catch((e) => MessageUtil.error("索引删除错误", e, () => reject(e)))
            );
            break;
          case "lifecycle":
            break;
        }
      });
    }
  }
});
</script>
<style lang="less">
.index-manage-drawer {
  .index-manage {
    position: absolute;
    top: 56px;
    left: 0;
    right: 0;
    bottom: 65px;
    overflow: hidden;

    .tab {
      position: absolute;
      top: 5px;
      left: 20px;
      right: 20px;
    }

    .content {
      position: absolute;
      top: 54px;
      left: 20px;
      right: 20px;
      bottom: 0;
      overflow: auto;
    }
  }

  .arco-drawer-footer {
    text-align: left !important;
  }
}
</style>
